iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 17
1
Modern Web

還在想要買哪一堂線上課程嗎?培養看文件的習慣吧!用 MDN 文件學後端:NodeJS & MongooseDB系列 第 17

17日: Express/Node introduction ( Node & Express 從何而生 、 有多熱門 、 主導性 、 Importing and creating modules )

  • 分享至 

  • xImage
  •  

承上篇 出處 , 有繁體版 ( 僅上半部分 ) 進入後自行點選

Node & Express 從何而生

2009年 , Node 起初只發佈在 Linux 上 ; NPM 在 2010 發佈 。
2012 支援 Windows , 現在的 LTS 版數是 Node v10.16.0 , 最新的版本是 12.7.0 ( 本篇鐵人賽撰文日期為 2019/10 ) 。
這在歷史上只佔很短暫渺小的片刻 , 點這裡連結到維基百科看更多 Node.js

Express 起初在 2010/11 發布 , 現在版本是 4.17.1 。 可以點擊 changelog 看更新資訊 , 還有在 GitHub 看更詳盡的發佈歷史紀錄

Node & Express 有多熱門

框架的流行性很重要 , 因為這是衡量有無持續在維運的指標 , 以及文件 、 添加函式庫 、 技術支援這些資源的指標 。
目前還沒有容易取得 、 明確的 ss 框架流行程度評測 , 雖然有像 Hot Frameworks 這類網站試著從 GitHub & StackOverflow 討論度來擷取熱門程度 。
而一個更值得探討的問題是 : 「 Node & Express 夠流行嗎 ? 」 這影響到是否有持續進化 、 能不能得到援助 、 學了 Express 是否能成為生財技能之一 。

根據 high profile companies 所述使用 Express 公司數量 , codebase 使用人數分佈 , 還有免費或付費的支援提供量 , Express 確實是個現正熱映中的框架 !

Express 主導性

框架常被稱為 opinionated 或 unopinionated
( 我將它翻譯為主導性 , 前者程度高 , 後者反之 ,在前幾日如何選框架的文章裡有提到 )

這個小節又再次解釋一次主導性 , 因前篇有提過了 , 這邊就簡單帶過 :
主導性高的框架 , 通常在面臨任務時會有一個強烈建議的正確方式 , 但因此導致彈性較低 、 較少的 components 選擇可使用;
主導性低的框架 , 反之較沒有受限的最佳解答 , 讓開發者更容易找到最適工具去解決任務 , 但這就要自己花時間去找適合自己的 components

Express 是主導性低的框架 , 我們可以插入自己喜歡的相容 middleware , 也可以決定要用一個還是多個檔案來架構 app , 還能用目錄是的架構 。
因為數量龐大 , 我們有時常會染上選擇困難症 !

Express code 的模樣

傳統資料導向的網站中 , web app 隨時待命接收來自 browser 的 HTTP req
當 app 接收到一個 req , 需要參照 URL patternPOST/GET data 。 而哪些是需要的項目 ? 視從 db 取出的讀寫資訊處理其他 req 而定 。 ( 蛤 ? )
App 將會回傳 res 給 browser , 通常會插入 HTML template 來動態產生這個 res

( 以下開始沒有繁中版 )
Express 提供一些 method 可以處理 HTTP 行為 & URL pattern
以及處理用何種 template ( view ) engin , 哪些 template files 在本地端 , 用什麼 templaterender res 。 ( 這部分我想可能是指編譯 、 打包 )

我們可以使用 middleware 提高 Express 對 cookies, sessions, getting POST/GET parameters ... 的支援
任意使用 Node 對 db 機制的支援 ( Express 沒有定義任何 db-related 行為 )

下方段落解釋一些常見、用 Express & Node 處理任務的 code

Helloworld Express

首先來看看標準的 Express Hello World 範例 , 我們下方會針對這個做討論

Tip: 如果已經安裝好 Express & Node ( 還沒的話點這裡 , 或見最下面補充懶人包 ) , 可以把這段 code 存在一個命名為 app.js 的檔案 , 並在 terminal 用這個指令執行它 : node ./app.js

var express = require('express');
var app = express();

app.get('/', function(req, res) {
  res.send('Hello World!');
});

app.listen(3000, function() {
  console.log('Example app listening on port 3000!');
});

( 上一篇是用 ES6 , 怎麼這邊又沒了 )
頭兩行 require() express module 且建立 Express app( 這個連結有很多 methods 可以看 )
這個物件通常會稱為 app , 帶有這些 methods : routing HTTP req, middleware 配置, 渲染 HTML views, registering template engin, 修改 app 設定來控制 app 行為 ( 如 : environment mode, route 定義是否區分大小寫 ... )

中段 app.get 開始的 code , 表示 route 定義app.get() method 是一個 callback function , 當帶有 網站根 path('/') 的 HTTP GET req 出現 , 這 function 會被呼叫
這 callback function 把 req, res 物件當作參數 , 然後呼叫 send() 作為回傳字串 'Hello World' 的 res

尾段啟動 port 3000 server , 還有打印註解 。 隨著這 server 運行 , 可以到瀏覽器輸入 localhost:3000 位置來看看這個範例

Importing and creating modules

接著我們要談談模組這回事 : 我們可以用 Node 裡的 require() function 引入一個或數個 JS 函式庫或檔案到其他的 code 裡面 。 Express 本身就是一個模組 , 而且我們會在 Express app 中用到 middleware & db libraries

下面的 code 顯示我們要怎麼引入模組 ( 以 Express 框架為例 ) , 首先呼叫 require() , 指定模組名稱並為字串型別 ( 這裡是'express' ) , 然後建立物件 ( 建立 Express app ) 。 我們就可以存取這個物件 / app 的 properties ( 屬性、特性 ) & functions 了

var express = require('express');
var app = express();

也可以創造自己的模組 , 然後用相同方式引入

Tip : 將來我們會想要建立自己的模組 , 因為這使我們 ( 原文 organise 疑似為 organize 拼字錯誤 ) 把 code 組織化 , 有利管理 。 一支獨立檔案的 app 不易理解及維護 , 使用模組可以幫助我們管理 namespace , 因為當我們使用模組時 , 只有由自己明確產出的變數會被引入 ( 蛤 ? 原文 : because only the variables you explicitly export are imported when you use a module. )

為了要讓模組可以外部引入 , 我們需要導出( exports ) 。 例如 : sqare.js 模組 exports area() & perimeter()

exports.area = functioin(width) { return width * width; };
exports.perimeter = functioin(width) { return 4 * width; };

這樣之後就可以引入 , 並呼叫這個被導出的 method

var square = require('./square'); // 省略副檔名
console.log('The area of a square with a width of 4 is ' + square.area(4));

Note : 也可以用絕對路徑 , 或用名字 , 像上面一開始的範例
如果不想一次只導出一個特性 , 改成導出完整的物件 , 我們用 module.export

module.exports = {
  area: function(width) {
    return width * width;
  },
       
  perimeter: function(width) {
    return 4 * width;
  }
};

可以把 exports 想像成 module.exportsshortcut
exports 只是一個在 module 被估算好之前 , 取得 module.exports 初始化的變數 ; 它的值是參考 ( reference to ) 一個物件 ( 在這個範例是空物件 ) , 這意味著 exports 含有一個和 module.exports 相同物件的參考 , 這也表示 assign 另一個值給 exports , 不會干涉到 module.exports
更多模組訊息詳見 Node API docs Moudules

最下面補充懶人包

Node & npm 可直接在官網安裝 , 如果想要控制版數則需要 NVM , 但因篇幅這裡先不提 。
要檢查有沒有安裝成功可以在專案資料夾下執行, 看有沒有回傳版數

$ node -v
$ npm -v

裝完 Node 之後, 在專案資料夾下執行以下指令安裝 Express

$ npm init
$ npm install express

上一篇
16日: Express/Node introduction ( Node 介紹 、 Hello Node.js 、 Express 介紹 )
下一篇
18日: Express/Node introduction ( 非同步 APIs 、 建立 route handlers 、 使用 middleware )
系列文
還在想要買哪一堂線上課程嗎?培養看文件的習慣吧!用 MDN 文件學後端:NodeJS & MongooseDB30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言